package com.transcasafe.eanpay.core.service;

import com.transcasafe.eanpay.core.config.EanPayConfig;
import com.transcasafe.eanpay.core.http.DefaultHttpClientBuilder;
import com.transcasafe.eanpay.core.http.HttpClient;
import com.transcasafe.eanpay.core.http.HttpMethod;
import com.transcasafe.eanpay.core.http.HttpRequest;
import com.transcasafe.eanpay.core.http.HttpResponse;
import com.transcasafe.eanpay.core.http.JsonRequestBody;
import com.transcasafe.eanpay.core.service.model.CreateReadiesPaymentRequest;
import com.transcasafe.eanpay.core.service.model.PaymentsPayRequest;
import com.transcasafe.eanpay.core.service.model.PaymentsPayResponse;
import com.transcasafe.eanpay.core.service.model.QueryAccountResponse;
import com.transcasafe.eanpay.core.service.model.RefundPaymentRequest;
import com.transcasafe.eanpay.core.service.model.RefundPaymentResponse;
import com.transcasafe.eanpay.core.service.model.UpdateLogisticsInfoRequest;
import com.transcasafe.eanpay.core.service.model.UpdateLogisticsInfoResponse;

import static java.util.Objects.requireNonNull;

public class EanPayCardService {
    private final HttpClient httpClient;
    private final String hostname;
    private final String mchNo;

    public EanPayCardService(HttpClient httpClient, String hostname, String mchNo) {
        this.httpClient = requireNonNull(httpClient);
        this.hostname = requireNonNull(hostname);
        this.mchNo = mchNo;
    }

    public static class Builder {
        private HttpClient httpClient;
        private String hostname;
        private String mchNo;

        public Builder config(EanPayConfig config) {
            this.httpClient = new DefaultHttpClientBuilder().config(config).build();
            this.mchNo = config.getMchNo();
            return this;
        }

        public Builder hostname(String hostname) {
            this.hostname = hostname;
            return this;
        }

        public EanPayCardService build() {
            return new EanPayCardService(httpClient, hostname, mchNo);
        }
    }

    public PaymentsPayResponse readiesPay(CreateReadiesPaymentRequest request) {
        HttpRequest httpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .addHeader("Content-Language", "en")
                .url(hostname + "/v1/card-pay/payments/readies-pay")
                .body(new JsonRequestBody.Builder().body(request.toJsonStr()).build())
                .build();
        HttpResponse<PaymentsPayResponse> response = httpClient.execute(httpRequest, PaymentsPayResponse.class);
        return response.getServiceResponse();
    }

    public PaymentsPayResponse pay(PaymentsPayRequest request) {
        HttpRequest httpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .addHeader("Content-Language", "en")
                .url(hostname + "/v1/card-pay/payments/pay")
                .body(new JsonRequestBody.Builder().body(request.toJsonStr()).build())
                .build();
        HttpResponse<PaymentsPayResponse> response = httpClient.execute(httpRequest, PaymentsPayResponse.class);
        return response.getServiceResponse();
    }

    public RefundPaymentResponse refund(RefundPaymentRequest request) {
        HttpRequest httpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .addHeader("Content-Language", "en")
                .url(hostname + "/v1/card-pay/payments/refund")
                .body(new JsonRequestBody.Builder().body(request.toJsonStr()).build())
                .build();
        HttpResponse<RefundPaymentResponse> response = httpClient.execute(httpRequest, RefundPaymentResponse.class);
        return response.getServiceResponse();
    }

    public QueryAccountResponse queryAccount() {
        HttpRequest httpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .addHeader("Content-Language", "en")
                .url(hostname + "/v1/card-pay/account/query")
                .body(null)
                .build();
        HttpResponse<QueryAccountResponse> response = httpClient.execute(httpRequest, QueryAccountResponse.class);
        return response.getServiceResponse();
    }

    public UpdateLogisticsInfoResponse updateLogisticsInfo(UpdateLogisticsInfoRequest request) {
        HttpRequest httpRequest = new HttpRequest.Builder()
                .httpMethod(HttpMethod.POST)
                .addHeader("Content-Language", "en")
                .url(hostname + "/v1/card-pay/payments/update-logistics-info")
                .body(new JsonRequestBody.Builder().body(request.toJsonStr()).build())
                .build();
        HttpResponse<UpdateLogisticsInfoResponse> response = httpClient.execute(httpRequest, UpdateLogisticsInfoResponse.class);
        return response.getServiceResponse();
    }
}
